package com.vt.exel;

import java.io.File;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;
import com.vt.exel.pattern.PatternReadFromSheets;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

/**
 * 
 * @author Vit
 * 
 */
public class ExelExtractor {
	/**
	 * Локальное хранилище позиций, вытянутых из exel
	 */
	public DataBuffer dataBuffer = new DataBuffer();
	/**
	 * Дополнительное временное хранилище для промежуточных операций
	 */
	public DataBuffer simpleBuffer = new DataBuffer();

	/**
	 * Чтение из exel-файла позиций для обработки
	 * 
	 * @param pathToExel Путь до форматированного файла с позициями
	 * @param patternReadFromSheets Паттерны определения кодов, веса и объема в листе
	 */
	public void exelReading(String pathToExel, PatternReadFromSheets patternReadFromSheets) {
		Preconditions.notBlank(pathToExel);
		Preconditions.notNull(pathToExel);
		try {
			for (int i = 0; i < patternReadFromSheets.numberOfSheets(); i++) {
				Workbook workbook = Workbook.getWorkbook(new File(pathToExel));
				Sheet sheet = workbook.getSheet(i);
				String localCode;
				Float localWeight;
				Float lovalVolume;
				String leftSideCode = "";
				String rightDiseCode = "";
				System.out.println("Обработка листа, количество строк: " + sheet.getRows() + " количество столбов: " + sheet.getColumns());
				for (int y = 1; y < sheet.getRows(); y++) {
					localCode = "";
					leftSideCode = "";
					rightDiseCode = "";
					localWeight = (float) 0;
					lovalVolume = (float) 0;
					// Получение Строки с кодом позиции
					if (patternReadFromSheets.isCodeDuality(i)) {
						leftSideCode = sheet.getCell(patternReadFromSheets.getCodeNo(i), y).getContents().trim();
						rightDiseCode = sheet.getCell(patternReadFromSheets.getCodeNo(i) + 1, y).getContents().trim();
						localCode = leftSideCode + " " + rightDiseCode;
					}
					if (!patternReadFromSheets.isCodeDuality(i)) {
						localCode = sheet.getCell(patternReadFromSheets.getCodeNo(i), y).getContents().trim();
					}
					// Получение не пустого веса позиции
					if (!sheet.getCell(patternReadFromSheets.getWeightNo(i), y).getContents().equals("")) {
						localWeight = Float.parseFloat((sheet.getCell(patternReadFromSheets.getWeightNo(i), y).getContents()));
					}
					// Получение не пустого объема позиции
					if (!sheet.getCell(patternReadFromSheets.getVolumeNo(i), y).getContents().equals("")) {
						// System.out.println(localCode);
						lovalVolume = Float.parseFloat(sheet.getCell(patternReadFromSheets.getVolumeNo(i), y).getContents());
					}
					if (localCode.trim().equals("")) {
						System.out.println("Обнаружено пустое поле, переход к следующему листу");
						break;
					}
					dataBuffer.setPosElement(localCode, localWeight, lovalVolume);
				}
			}
			System.out.println("Позиции загружены из Exel-документа");
		} catch (BiffException e) {
			System.out.println("BiffException");
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("IOException");
			e.printStackTrace();
		}
	}

	/**
	 * Проверка выгруженных из exel позиций на пустые значения веса/объема с последующей их выгрузкой в отдельный файл
	 * 
	 * @param pathToExel Путь до выгружаемого файла
	 */
	public void verifyEmpty(String pathToExel) {
		Preconditions.notBlank(pathToExel);
		Preconditions.notNull(pathToExel);
		try {
			WritableWorkbook workbook = Workbook.createWorkbook(new File(pathToExel));
			WritableSheet sheet = workbook.createSheet("Пустые значения", 0);
			WritableFont arial16font = new WritableFont(WritableFont.ARIAL, 16);
			WritableCellFormat arial16format = new WritableCellFormat(arial16font);
			sheet.addCell(new Label(0, 0, "Название фильтра", arial16format));
			sheet.addCell(new Label(1, 0, "Объем фильтра", arial16format));
			sheet.addCell(new Label(2, 0, "Вес фильтра", arial16format));
			WritableFont arial14font = new WritableFont(WritableFont.ARIAL, 14);
			WritableCellFormat arial14format = new WritableCellFormat(arial14font);
			int i = 1;
			for (PosElement posElement : dataBuffer.elements) {
				if ((posElement.getVolume() == 0) || (posElement.getWeight() == 0)) {
					sheet.addCell(new Label(0, i, posElement.getCode(), arial14format));
					sheet.addCell(new Label(1, i, posElement.getVolume().toString(), arial14format));
					sheet.addCell(new Label(2, i, posElement.getWeight().toString(), arial14format));
					simpleBuffer.elements.add(posElement);
					i++;
				}
			}
			for (PosElement buffer : simpleBuffer.elements) {
				dataBuffer.elements.remove(buffer);
			}
			simpleBuffer.elements.clear();
			workbook.write();
			workbook.close();
			/*
			 * for (PosElement posElement : dataBuffer.elements) { System.out.println(posElement.getCode() + " " + posElement.getVolume() + " " +
			 * posElement.getWeight()); }
			 */
			System.out.println("Пустые позиции выгружены в отдельный файл");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (RowsExceededException e) {
			e.printStackTrace();
		} catch (WriteException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Проверка выгруженных из exel позиций на ошибки в названиях при сверке с БД,с последующим экспортом последних в отдельный файл
	 * 
	 * @param pathToExel Путь до выгружаемого файла
	 */
	public void verifyErrors(String pathToExel) {
		try {
			List<String> listCodesFromDb = new ArrayList<String>();
			String driverName = "com.mysql.jdbc.Driver";
			Class.forName(driverName);
			String serverName = "localhost";
			String serverPort = "3306";
			String mydatabase = "goodwill";
			String url = "jdbc:mysql://" + serverName + ":" + serverPort + "/" + mydatabase;
			String username = "goodwill-store";
			String password = "6533xx";
			Connection connection = (Connection) DriverManager.getConnection(url, username, password);
			String query = "SELECT Code FROM goods";
			Statement statement = (Statement) connection.createStatement();
			ResultSet resultSet = statement.executeQuery(query);
			// Заполнение коллекции значениями кодов из БД
			while (resultSet.next()) {
				listCodesFromDb.add(resultSet.getString(1));
			}
			connection.close();
			boolean inBd = false;
			// Сверка кодов из БД и Exel
			for (PosElement codeFromExel : dataBuffer.elements) {
				inBd = false;
				for (String codeFromDb : listCodesFromDb) {
					if (codeFromExel.getCode().equals(codeFromDb)) {
						inBd = true;
					}
				}
				// Запонение промежуточного буфера позициями содержащими ошибки в названии
				if (!inBd) {
					simpleBuffer.elements.add(codeFromExel);
				}
			}
			System.out.println("Сверка позиций с БД проведена");
			// Запись позиций содержащих ошибки в exel файл
			WritableWorkbook workbook = Workbook.createWorkbook(new File(pathToExel));
			WritableSheet sheet = workbook.createSheet("Значения с ошибкой", 0);
			WritableFont arial16font = new WritableFont(WritableFont.ARIAL, 16);
			WritableCellFormat arial16format = new WritableCellFormat(arial16font);
			sheet.addCell(new Label(0, 0, "Название фильтра", arial16format));
			sheet.addCell(new Label(1, 0, "Объем фильтра", arial16format));
			sheet.addCell(new Label(2, 0, "Вес фильтра", arial16format));
			WritableFont arial14font = new WritableFont(WritableFont.ARIAL, 14);
			WritableCellFormat arial14format = new WritableCellFormat(arial14font);
			int i = 1;
			for (PosElement posElement : simpleBuffer.elements) {
				sheet.addCell(new Label(0, i, posElement.getCode(), arial14format));
				sheet.addCell(new Label(1, i, posElement.getVolume().toString(), arial14format));
				sheet.addCell(new Label(2, i, posElement.getWeight().toString(), arial14format));
				i++;
			}
			for (PosElement buffer : simpleBuffer.elements) {
				dataBuffer.elements.remove(buffer);
			}
			simpleBuffer.elements.clear();
			workbook.write();
			workbook.close();
			System.out.println("Позиции содержащие ошибку в названии выгружены в отдельный файл");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (RowsExceededException e) {
			e.printStackTrace();
		} catch (WriteException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Выгрузка в отдельный файл позиций, готовых для выгрузки, для их последней, "визуальной проверки"
	 * 
	 * @param pathToExel Путь до выгружаемого файла
	 */
	public void getListForUpload(String pathToExel) {
		try {
			WritableWorkbook workbook = Workbook.createWorkbook(new File(pathToExel));
			WritableSheet sheet = workbook.createSheet("Загружаемые фильтры", 0);
			WritableFont arial16font = new WritableFont(WritableFont.ARIAL, 16);
			WritableCellFormat arial16format = new WritableCellFormat(arial16font);
			sheet.addCell(new Label(0, 0, "Название фильтра", arial16format));
			sheet.addCell(new Label(1, 0, "Объем фильтра", arial16format));
			sheet.addCell(new Label(2, 0, "Вес фильтра", arial16format));
			WritableFont arial14font = new WritableFont(WritableFont.ARIAL, 14);
			WritableCellFormat arial14format = new WritableCellFormat(arial14font);
			int i = 1;
			for (PosElement posElement : dataBuffer.elements) {
				sheet.addCell(new Label(0, i, posElement.getCode(), arial14format));
				sheet.addCell(new Label(1, i, posElement.getVolume().toString(), arial14format));
				sheet.addCell(new Label(2, i, posElement.getWeight().toString(), arial14format));
				i++;
			}
			workbook.write();
			workbook.close();
			System.out.println("Позиции для загрузки выгружены в отдельный файл");
		} catch (RowsExceededException e) {
			e.printStackTrace();
		} catch (WriteException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Загрузка в базу данных проверенных значений веса и массы
	 */
	public void uploadToDB() {
		try {
			String driverName = "com.mysql.jdbc.Driver";
			Class.forName(driverName);
			String serverName = "192.168.0.5";
			String serverPort = "3306";
			String mydatabase = "goodwill-store";
			String url = "jdbc:mysql://" + serverName + ":" + serverPort + "/" + mydatabase;
			String username = "goodwill-store";
			String password = "6533xx";
			Connection connection = (Connection) DriverManager.getConnection(url, username, password);
			Statement statement = (Statement) connection.createStatement();
			String quo = "'";
			System.out.println("Заливка в БД: ");
			for (PosElement posElement : dataBuffer.elements) {
				String query = "UPDATE goods" + " SET Volume=" + quo + posElement.getVolume() + quo + "," + " Weight=" + quo + posElement.getWeight() + quo + " WHERE Code=" + quo + posElement.getCode() + quo;
				System.out.println(query);
				statement.executeUpdate(query);	
			}
			connection.close();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}
